<#assign object = doc.object>
package ${object.package}.service.base;

import java.util.*;
<#if object.attributes.xml[0]?? || object.attributes.date[0]?? || object.attributes.datetime[0]??>
import java.util.logging.Level;
</#if>
import java.util.logging.Logger;
<#if object.attributes.xml[0]??>
import redora.util.DefaultErrorHandler;
import redora.util.SchemaValidator;
</#if>
<#if doc["/object/attributes/*[@regexp]"][0]??>
import java.util.regex.Matcher;
import java.util.regex.Pattern;
</#if>
import redora.api.*;
import redora.api.BusinessRuleViolation.Action;
import redora.api.BusinessRuleViolation.StandardRule;
import redora.exceptions.BusinessRuleViolationException;

import ${object.package}.model.*;
import ${object.package}.model.fields.${object.name}Fields;
import ${object.package}.service.${object.name}Util;

public abstract class ${object.name}BusinessRulesBase {
	private Logger l = Logger.getLogger("${object.package}.service.base.${object.name}BusinessRulesBase");

	private ${object.name}Util util;
	
	protected ${object.name}BusinessRulesBase (${object.name}Util util) {
		this.util = util;
	}

	<#list doc["/object/attributes/*[@regexp]"] as att>
		<#if att?node_name == "date">
	private java.text.SimpleDateFormat dateFormat = new java.text.SimpleDateFormat("yyyy-mm-dd hh:mm:ss");
	private Pattern ${att.@fieldName}Pattern = Pattern.compile("${att.@regexp}");
		<#elseif att?node_name == "string">
	private Pattern ${att.@fieldName}Pattern = Pattern.compile("${att.@regexp}");
		</#if>
	</#list>
	
	<#list doc["/object/businessRules/businessRule"] as br>
	/** ${br.@javadoc} */
	public static final int BR_${br.@number} = ${br.@number};
	</#list>
	
	private Set<BusinessRuleViolation> onAll(${object.name} pojo, Action action) throws BusinessRuleViolationException {
		Set<BusinessRuleViolation> retVal = new HashSet<BusinessRuleViolation>();
		<#list object.formScope?children as att>
			<#if att?node_type == "element">
				<#if att.@notnull[0]?? && att.@notnull == "true">
					<#if att?node_name == "string">
		if (pojo.${att.@fieldName} == null || pojo.${att.@fieldName}.trim().length() == 0) {
			retVal.add(new BusinessRuleViolation(
				pojo, ${object.name}Fields.${att.@fieldName}, StandardRule.NotNull.ruleId, action));
		}
					<#elseif att?node_name == "object">
		if (pojo.${att.@fieldName}Id == null) {
			retVal.add(new BusinessRuleViolation(
				pojo, ${object.name}Fields.${att.@fieldName}Id, StandardRule.NotNull.ruleId, action));
		}
					<#elseif att?node_name != "object">
		if (pojo.${att.@fieldName} == null) {	
			retVal.add(new BusinessRuleViolation(
				pojo, ${object.name}Fields.${att.@fieldName}, StandardRule.NotNull.ruleId, action));
		}
					</#if>
				</#if>
				<#if att.@regexp[0]??>
		if (pojo.dirty.containsKey(${object.name}Fields.${att.@fieldName}) && pojo.${att.@fieldName} != null) {
					<#if att?node_name == "date" || att?node_name == "datetime">
			try {
				Matcher ${att.@fieldName}Matcher = ${att.@fieldName}Pattern.matcher(dateFormat.format(pojo.${att.@fieldName}));
				if( !${att.@fieldName}Matcher.matches()) {
					retVal.add(new BusinessRuleViolation(pojo, ${object.name}Fields.${att.@fieldName}
						, StandardRule.MatchRegexp.ruleId, action));
				}
			} catch(Exception e) {
				l.log(Level.SEVERE, "Failed to check date ${att.@fieldName}'s for regexp ${att.@regexp} ", e);
				throw new BusinessRuleViolationException("Failed to check date ${att.@fieldName}'s regexp ${att.@regexp}",e);
			}
					<#elseif att?node_name == "string">
			Matcher ${att.@name}Matcher = ${att.@name}Pattern.matcher(pojo.${att.@fieldName});
			if ( !${att.@fieldName}Matcher.matches()) {
				retVal.add(new BusinessRuleViolation(pojo, ${object.name}Fields.${att.@fieldName}
					, StandardRule.MatchRegexp.ruleId, action));
			}
					<#else>
					HOLA: unspecified regexp in ${att.@name}. Check the model, XSD or fix this template
					</#if>
		}
				</#if>
				<#if att.@maxlength[0]??>
		if (pojo.dirty.containsKey(${object.name}Fields.${att.@fieldName}) && pojo.${att.@fieldName} != null && pojo.${att.@fieldName}.length() > ${att.@maxlength}) {
			retVal.add(new BusinessRuleViolation(pojo, ${object.name}Fields.${att.@fieldName}, StandardRule.MaxLength.ruleId, action));
		}
				</#if>
				<#if att?node_name == "xml">
		if (pojo.dirty.containsKey(${object.name}Fields.${att.@fieldName})) {
			try {
				SchemaValidator ${att.@fieldName}Validator =
					new SchemaValidator(getClass(),"${att.@className}.xsd");

				DefaultErrorHandler errorHandler = new DefaultErrorHandler();
				${att.@fieldName}Validator.validate(util.marshall(pojo.${att.@fieldName}), errorHandler);
				if (errorHandler.getErrors().hasContent()) {
					l.log(Level.FINE,"Failed to do checking according to XSD file for ${att.@fieldName}");
					retVal.add(new BusinessRuleViolation(pojo, ${object.name}Fields.${att.@fieldName}, StandardRule.XsdValidation.ruleId, action));
				}
			} catch (Exception e) {
				l.log(Level.SEVERE, "Failed to do XSD check for ${att.@className}. Your XSD is maybe not in the classpath yet, so run maven build first.", e);
				throw new BusinessRuleViolationException("Failed to do XSD check for ${att.@className}. Your XSD is maybe not in the classpath yet, so run maven build first.", e);
			}	
		}
				</#if>
			</#if>
		</#list>
	
		return retVal;
	}

	public Set<BusinessRuleViolation> onInsert(${object.name} pojo) throws BusinessRuleViolationException {
		return onAll(pojo, Action.Insert);
	}
	public Set<BusinessRuleViolation> onUpdate(${object.name} pojo) throws BusinessRuleViolationException {
		return onAll(pojo, Action.Update);
	}
	public Set<BusinessRuleViolation> onDelete(${object.name} pojo) throws BusinessRuleViolationException {
		return new HashSet<BusinessRuleViolation>();
	}
}
